﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;

namespace MyPetHub.Common
{
    public class ObjectReflection
    {
        public static PropertyInfo[] GetPropertyInfos(Type type)
        {
            return type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
        }

        /// <summary>
        /// 根据属性名对应关系，将Source对象的数据赋值到Target对象
        /// </summary>
        /// <param name="s">赋值对象</param>
        /// <param name="t">被赋值对象</param>
        public static void AutoMapping<Source, Target>(Source s, Target t)
        {
            PropertyInfo[] pps = GetPropertyInfos(s.GetType());
            Type target = t.GetType();

            foreach (var pp in pps)
            {
                PropertyInfo targetPP = target.GetProperty(pp.Name);

                if (targetPP == null)
                    continue;

                object value = pp.GetValue(s, null);
                targetPP.SetValue(t, value, null);
            }
        }

        /// <summary>
        /// 根据属性名对应关系，将Source对象的数据赋值到Target对象,排除带有exclusionAttribute特性的字段
        /// </summary>
        /// <param name="s">赋值对象</param>
        /// <param name="t">被赋值对象</param>
        /// <param name="exclusionAttribute">排除的特性，带有该特性的字段将不被赋值</param>
        public static void AutoMappingWithExclusionAttribute<Source, Target>(Source s, Target t,Type exclusionAttribute)
        {
            PropertyInfo[] pps = GetPropertyInfos(s.GetType());
            Type target = t.GetType();

            foreach (var pp in pps)
            {
                PropertyInfo targetPP = target.GetProperty(pp.Name);

                if (targetPP == null)
                    continue;

                if (targetPP.CustomAttributes.Where(x => x.AttributeType == exclusionAttribute).Any())
                    continue;

                object value = pp.GetValue(s, null);
                targetPP.SetValue(t, value, null);
            }
        }
    }
}